/**
 * Shopro-request
 * @description api模块管理，loading配置，请求拦截，错误处理
 */

import axios from 'axios';
import {
	baseUrl
} from '@/sheep/config';
import $store from '@/sheep/store';
import {
	showAuthModal
} from '@/sheep/hooks/useModal';
import $helper from '@/sheep/helper'
import Cookie from 'js-cookie'
import sheep from '@/sheep'

const options = {
	// 显示操作成功消息 默认不显示
	showSuccess: true,
	// 成功提醒 默认使用后端返回值
	successMsg: '',
	// 显示失败消息 默认显示
	showError: true,
	// 失败提醒 默认使用后端返回信息
	errorMsg: '',
	// 显示请求时loading模态框 默认显示
	showLoading: true,
	// loading提醒文字
	loadingMsg: '加载中',
	// 需要授权才能请求 默认放开
	auth: false,
	// 文件上传
	fileUpload: false
};

// Loading全局实例
let LoadingInstance = {
	target: null,
	count: 0,
};

const whiteList = ['pages/index/sharing']

/**
 * 关闭loading
 */
function closeLoading() {
	if (LoadingInstance.count > 0) LoadingInstance.count--;
	if (LoadingInstance.count === 0) uni.hideLoading();
}

/**
 * @description 请求基础配置 可直接使用访问自定义请求
 */
const axiosInstance = axios.create({
	baseURL: baseUrl, //通过发行-h5打包时打开
	timeout: 8000,
	withCredentials: true,
	headers: {
		'Access-Control-Allow-Origin': '*',
		'Access-Control-Allow-Methods': '*',
		'Access-Control-Allow-Headers': '*',
	},
	custom: options,
});

/**
 * @description 请求拦截器
 */
axiosInstance.interceptors.request.use(
	(config) => {
		// 权限控制
		if (config.custom.auth && !$store('user').isLogin) {
			$helper.toast('请先登录')
			return Promise.reject();
		}
		if (config.custom.fileUpload) {
			config.headers['Content-type'] = 'multipart/form-data'
		}
		// 全局loading
		if (config.custom.showLoading) {
			LoadingInstance.count++;
			LoadingInstance.count === 1 &&
				uni.showLoading({
					title: config.custom.loadingMsg,
					mask: true,
					fail: () => {
						uni.hideLoading();
					},
				});
		}
		// get请求查询，参数序列化
		if (config.method === "GET") {
			config.paramsSerializer = function(params) {
				return qs.stringify(params, {
					arrayFormat: "repeat"
				});
			};
		}
		return config;
	},
	// 错误处理
	(error) => {
		return Promise.reject(error);
	},
);

/**
 * @description 响应拦截器
 */
axiosInstance.interceptors.response.use(
	(response) => {
		const userStore = $store('user');
		// 自动设置登陆令牌
		const hasToken = uni.getStorageSync('token');
		if (!hasToken) {
			$store('user').setToken(Cookie.get('token'));
		}
		response.config.custom.showLoading && closeLoading();
		if (response.data.code !== 200) {
			if (response.config.custom.showError) {
				uni.showToast({
					title: response.data.message || '服务器开小差啦,请稍后再试~',
					icon: 'none',
					mask: true,
				});
			}
			// 登录过期
			if (response.data.code == 401) {
				let {
					pagePath
				} = sheep.$helper.getCurrentPagePath();
				if (!whiteList.includes(pagePath)) {
					userStore.logout();
					sheep.$router.go('/pages/index/login'); // 跳转登录页
				}
			}
			return Promise.reject(response.data); //.catch()捕获
		} else {
			if (
				response.data.message !== '' &&
				response.config.custom.showSuccess
			) {
				uni.showToast({
					title: response.config.custom.successMsg || response.data.msg || response.data.message,
					icon: 'none',
				});
			}
			return Promise.resolve(response.data); //.then()捕获
		}
	},
	// 错误处理
	(error) => {
		const userStore = $store('user');
		const isLogin = userStore.isLogin;
		let errorMessage = '网络请求出错';
		if (error !== undefined) {
			switch (error.status) {
				case 400:
					errorMessage = '请求错误';
					break;
				case 401:
					if (isLogin) {
						errorMessage = '您的登陆已过期';
					} else {
						errorMessage = '请先登录';
					}
					userStore.logout();
					sheep.$router.go('/pages/index/login'); // 跳转登录页
					break;
				case 403:
					errorMessage = '权限不足';
					// TODO
					break;
				case 404:
					errorMessage = '请求出错';
					break;
				case 408:
					errorMessage = '请求超时';
					break;
				case 429:
					errorMessage = '请求频繁, 请稍后再访问';
					break;
				case 500:
					errorMessage = '服务器开小差啦,请稍后再试~';
					break;
				case 501:
					errorMessage = '服务未实现';
					break;
				case 502:
					errorMessage = '网络错误';
					break;
				case 503:
					errorMessage = '服务不可用';
					break;
				case 504:
					errorMessage = '网络超时';
					break;
				case 505:
					errorMessage = 'HTTP版本不受支持';
					break;
			}
		}

		if (error && error.config) {
			if (error.config.custom.showError === true) {
				uni.showToast({
					title: errorMessage,
					icon: 'none',
					mask: true,
				});
			}
			error.config.custom.showLoading && closeLoading();
		}

		return Promise.reject(false)
	},
);

const Request = (config) => {
	return axiosInstance(config);
};

export default Request;